﻿using Common.Exceptions;
using Common.Models;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using Wallpaper.Data.Context;
using Wallpaper.Data.IDal;
using Wallpaper.Models.DTOs.Base;
using Wallpaper.Models.DTOs.Responses;
using Wallpaper.Models.Entities;
using Wallpaper.Services.IService;


namespace Wallpaper.Services.Service
{
    public class DownloadRecordService : IDownloadRecordService
    {



        readonly IDownloadRecordDal _downloadRecordDal;
        readonly ILogger<DownloadRecordService> _logger;
        readonly WallpaperDbContext _dbContext;


        public DownloadRecordService(IDownloadRecordDal downloadRecordDal, 
            ILogger<DownloadRecordService> 
            logger, WallpaperDbContext dbContext)
        {
            _downloadRecordDal = downloadRecordDal;
            _logger = logger;
            _dbContext = dbContext;
        }

        private const int FreeDownloadsPerDay = 3;
        private const int PointsCostPerDownload = 30;

        public async Task<bool> CreateAsync(string wallpaperId, string userId)
        {
            // 使用EF Core的事务
            await using var transaction = await _dbContext.Database.BeginTransactionAsync();
            try
            {
                // 1. 验证用户是否存在
                User user = await _dbContext.Users.FirstOrDefaultAsync(u => u.Id == userId);
                if (user == null)
                {
                    throw new BusinessException("用户不存在或数据异常", 500);
                }

                // 2. 检查是否需要重置每日免费下载次数
                if (user.LastDownloadDate.Date < DateTime.Today)
                {
                    user.TodayFreeDownloadCount = FreeDownloadsPerDay;
                    user.LastDownloadDate = DateTime.Now;
                }

                // 3. 判断下载扣费逻辑
                int pointsCost = 0;
                if (user.TodayFreeDownloadCount > 0)
                {
                    user.TodayFreeDownloadCount--;
                    pointsCost = 0;
                }
                else
                {
                    if (user.Points < PointsCostPerDownload)
                    {
                        throw new InsufficientPointsException("积分不足");
                    }

                    pointsCost = PointsCostPerDownload;
                    user.Points -= PointsCostPerDownload;
                }

                // 4. 双重验证
                if (user.TodayFreeDownloadCount <= 0 && user.Points < 30)
                {
                    throw new InsufficientPointsException();
                }

                // 5. 创建下载记录实体
                DownloadRecord download = new DownloadRecord
                {
                    WallpaperId = wallpaperId,
                    UserId = userId,
                    PointsCost = pointsCost,
                    CreatedAt = DateTime.Now
                };

                // 6. 保存到数据库
                bool result = await _downloadRecordDal.CreateEntityAsync(download);
                if (!result)
                {
                    throw new Exception("创建下载记录失败");
                }

                // 7. 更新用户信息
                _dbContext.Users.Update(user);
                await _dbContext.SaveChangesAsync();

                // 提交事务
                await transaction.CommitAsync();

                return true;
            }
            catch
            {
                // 发生异常时回滚事务
                await transaction.RollbackAsync();
                throw; // 重新抛出异常
            }
        }


        /// <summary>
        /// 用户下载壁纸历史 
        /// </summary>
        /// <param name="wallpapersType"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<PagedResult<DownloadRecordUserResponse>> DownloadHistory(QueryRequest request,string userId)
        {
            var queryable =
                          (from record in _downloadRecordDal.GetDbSet<DownloadRecord>()
                              .Where(r => r.UserId == userId)  
                           join user in _downloadRecordDal.GetDbSet<User>()
                               on record.UserId equals user.Id
                           join wallpaper in _downloadRecordDal.GetDbSet<Wallpapers>()
                               on record.WallpaperId equals wallpaper.Id
                           join category in _downloadRecordDal.GetDbSet<Category>()
                               on wallpaper.CategoryId equals category.Id
                           select new DownloadRecordUserResponse
                           {
                               Id=record.Id,
                               WallpaperId = wallpaper.Id,
                               FileUrl = wallpaper.FileUrl,
                               TypeName = category.Name,
                               CreateAt=record.CreatedAt

                           });
            if (!string.IsNullOrEmpty(request.Keyword))
            {
                queryable = queryable.Where(w => w.TypeName.Equals(request.Keyword));
            }
            var totalCount = await queryable.CountAsync();

            // 3. 添加排序（按下载时间倒序）
            queryable = queryable.OrderByDescending(x => x.CreateAt);

            var items = await queryable
                .Skip((request.Page - 1) * request.PageSize)
                .Take(request.PageSize)
                .ToListAsync();

            return new PagedResult<DownloadRecordUserResponse>
            {
                Page = request.Page,
                PageSize = request.PageSize,
                TotalCount = totalCount,
                Items = items
            };
        }


        /// <summary>
        /// 获取所有用户下载历史
        /// </summary>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<PagedResult<DownloadRecordResponse>> UsersDownloadHistory(TimeRangeQuery query)
        {
            var queryable =
                          (from record in _downloadRecordDal.GetDbSet<DownloadRecord>()
                              
                           join user in _downloadRecordDal.GetDbSet<User>()
                               on record.UserId equals user.Id
                           join wallpaper in _downloadRecordDal.GetDbSet<Wallpapers>()
                               on record.WallpaperId equals wallpaper.Id
                           join category in _downloadRecordDal.GetDbSet<Category>()
                               on wallpaper.CategoryId equals category.Id
                           select new DownloadRecordResponse
                           {
                               Id=record.Id,
                               WallpaperId = wallpaper.Id,
                               UserId = user.Id,
                               UserNickName = user.Nickname,
                               Points = record.PointsCost,
                               FileUrl = wallpaper.FileUrl,
                               TypeName = category.Name,
                               CreateAt =record.CreatedAt
                           });
            // 1. 关键词搜索
            if (!string.IsNullOrEmpty(query.Keyword))
            {
                queryable = queryable.Where(w => w.TypeName.Contains(query.Keyword));
            }
            // 2. 时间范围搜索（重要！）
            if (query.StartTime.HasValue)
            {
                queryable = queryable.Where(x => x.CreateAt >= query.StartTime.Value);
            }

            if (query.EndTime.HasValue)
            {
                // 注意：结束时间通常要包含当天，所以用 <= EndTime.Value.Date.AddDays(1)
                queryable = queryable.Where(x => x.CreateAt < query.EndTime.Value.Date.AddDays(1));
            }

            var totalCount = await queryable.CountAsync();
            // 3. 添加排序（按下载时间倒序）
            queryable = queryable.OrderByDescending(x => x.CreateAt);

            var items = await queryable
                .Skip((query.Page - 1) * query.PageSize)
                .Take(query.PageSize)
                .ToListAsync();
            return new PagedResult<DownloadRecordResponse>
            {
                Page = query.Page,
                PageSize = query.PageSize,
                TotalCount = totalCount,
                Items = items
            };

        }

        /// <summary>
        /// 根据id删除下载记录
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<bool> DeleteAsync(string id)
        {
            return await _downloadRecordDal.DeleteByIdAsync(id);
        }
    }
}
